/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { computed, defineComponent, onMounted, ref, SetupContext } from 'vue';
import { TooltipProps, tooltipProps } from './tooltip.props';

import './tooltip.css';
import { useTooltipPosition } from './composition/use-tooltip-position';

export default defineComponent({
    name: 'FTooltip',
    props: tooltipProps,
    emits: ['click'] as (string[] & ThisType<void>) | undefined,
    setup(props: TooltipProps, context: SetupContext) {
        const isTextContext = ref(true);
        const arrowRef = ref<any>();
        const tooltipRef = ref<any>();
        const tooltipInnerRef = ref<any>();
        const placement = ref(props.placement.split('-')[0]);
        const tooltipClass = computed(() => {
            const classObject = {
                tooltip: true,
                show: true
            } as any;
            const tooltipClassName = `bs-tooltip-${placement.value}`;
            classObject[tooltipClassName] = true;
            return classObject;
        });

        const { scrollLeft, scrollTop } = document.documentElement;

        const shouldShowTooltipText = computed(() => isTextContext.value);

        const tooltipText = computed(() => props.content);

        const tooltipLeftPosition = ref('0px');

        const tooltipTopPosition = ref('0px');

        const tooltipRightPosition = ref('');

        const tooltipStyle = computed(() => {
            const styleObject = {
                left: tooltipLeftPosition.value,
                top: tooltipTopPosition.value
            };
            return styleObject;
        });

        const arrowLeftPosition = ref('');

        const arrowTopPosition = ref('');

        const arrowStyle = computed(() => {
            const styleObject = {
                left: arrowLeftPosition.value,
                top: arrowTopPosition.value
            };
            return styleObject;
        });

        onMounted(() => {
            if (arrowRef.value && tooltipRef.value && tooltipInnerRef.value && props.reference) {
                const { tooltipPlacement, tooltipPosition } = useTooltipPosition(
                    props,
                    context,
                    props.reference.getBoundingClientRect(),
                    tooltipRef.value.getBoundingClientRect(),
                    tooltipInnerRef.value.getBoundingClientRect(),
                    arrowRef.value.getBoundingClientRect()
                );
                tooltipLeftPosition.value = `${tooltipPosition.value.tooltip.left + scrollLeft}px`;
                tooltipTopPosition.value = `${tooltipPosition.value.tooltip.top + scrollTop}px`;
                arrowLeftPosition.value = `${tooltipPosition.value.arrow.left}px`;
                arrowTopPosition.value = `${tooltipPosition.value.arrow.top}px`;
                placement.value = tooltipPlacement.value;
            }
        });

        function onClick($event: MouseEvent) {
            context.emit('click', $event);
        }

        return () => {
            return (
                <div ref={tooltipRef} class={tooltipClass.value} style={tooltipStyle.value} onClick={onClick}>
                    <div ref={arrowRef} class="arrow" style={arrowStyle.value}></div>
                    <div ref={tooltipInnerRef} class="tooltip-inner">
                        <div class="tooltip-tmpl">
                            {shouldShowTooltipText.value && <div class="tooltip-text" v-html={tooltipText.value}></div>}
                        </div>
                    </div>
                </div>
            );
        };
    }
});
